package com.inforim.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.security.auth.login.LoginException;

import com.cognos.developer.schemas.bibus._3.BaseClass;
import com.cognos.developer.schemas.bibus._3.ContentManagerServiceStub;
import com.cognos.developer.schemas.bibus._3.Group;
import com.cognos.developer.schemas.bibus._3.Policy;
import com.cognos.developer.schemas.bibus._3.PropEnum;
import com.cognos.developer.schemas.bibus._3.QueryOptions;
import com.cognos.developer.schemas.bibus._3.Role;
import com.cognos.developer.schemas.bibus._3.SearchPathMultipleObject;
import com.cognos.developer.schemas.bibus._3.Sort;
import com.inforim.cognos.CognosClient;
import com.inforim.cognos.utils.CognosHelper;

public class OutputAuthMember {
	public Map<String, String> authCache = new HashMap<String, String>();
	public List<String> folders = new ArrayList<String>();
	public List<String> packages = new ArrayList<String>();

	public String getRolePerFromCogObj(CognosClient client,
			String obj_searchpath) {
		String output = "";
		output = obj_searchpath + ":\r\n";
		
		BaseClass[] results = new BaseClass[0];
		ContentManagerServiceStub cmServiceStub = (ContentManagerServiceStub) client
				.getService("ContentManagerService");
		try {
			results = cmServiceStub.query(new SearchPathMultipleObject(
					obj_searchpath), new PropEnum[] { PropEnum.searchPath,
					PropEnum.policies }, new Sort[0], new QueryOptions());
		} catch (RemoteException remoteEx) {
			System.out.println("Caught Remote Exception:\n");
			remoteEx.printStackTrace();
		}

		for (int i = 0; i < results[0].getPolicies().getValue().length; ++i) {
			Policy pol = results[0].getPolicies().getValue()[i];
			String tempStr=getUserFromRole(cmServiceStub, pol.getSecurityObject()
					.getSearchPath().getValue());
			
			output += tempStr;
		}
		
		return output;
	}

	public String getUserFromRole(ContentManagerServiceStub cmServiceStub,
			String rolesearchpath) {
		String output = "";
		if (authCache.containsKey(rolesearchpath)) {
			output += authCache.get(rolesearchpath);
			return output;
		}
		PropEnum[] props = { PropEnum.searchPath, PropEnum.defaultName,
				PropEnum.members };
		if (cmServiceStub != null) {
			Sort[] sortArray = { new Sort() };
			try {
				BaseClass[] bc = cmServiceStub.query(
						new SearchPathMultipleObject(rolesearchpath), props,
						sortArray, new QueryOptions());
				if (bc == null)
					System.out
							.println("\n\nError occurred in function viewAll.");
				if (bc.length <= 0) {
					System.out.println("There are currently no user.");
				}
				output += getAccount(bc, cmServiceStub,rolesearchpath);

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		authCache.put(rolesearchpath, output);
		return output;
	}

	private String getAccount(BaseClass[] bc,
			ContentManagerServiceStub cmServiceStub,String parentName) throws RemoteException {

		
		String output = "";
		
		Sort[] sortArray = { new Sort() };
		PropEnum[] props = { PropEnum.searchPath, PropEnum.defaultName,
				PropEnum.members };

		BaseClass[] bcchildren = new BaseClass[1];
		for (int i = 0; (bc != null) && (i < bc.length); ++i) {
			if (bc[i] instanceof Role) {
				String name=((Role)bc[i]).getDefaultName().getValue();
				bcchildren = ((Role) bc[i]).getMembers().getValue();
				output += ((Role) bc[i]).getDefaultName().getValue() + "->\r\n";
				output += getAccount(bcchildren, cmServiceStub,name);
			} else if (bc[i] instanceof Group) {
				String name=((Group)bc[i]).getDefaultName()==null?null:((Group)bc[i]).getDefaultName().getValue();
				if (((Group) bc[i]).getMembers() != null) {
					bcchildren = ((Group) bc[i]).getMembers().getValue();
					output += ((Group) bc[i]).getDefaultName().getValue()
							+ "->\r\n";
				} else {
					bcchildren = cmServiceStub.query(
							new SearchPathMultipleObject(bc[i].getSearchPath()
									.getValue()), props, sortArray,
							new QueryOptions());
				}

				output += getAccount(bcchildren, cmServiceStub,name);
			} else {
				bcchildren[0] = bc[i];
					BaseClass[] bcuser = cmServiceStub.query(
							new SearchPathMultipleObject(bc[i].getSearchPath()
									.getValue()), props, sortArray,
							new QueryOptions());

					String mudid = bcuser[0].getSearchPath().getValue();
					int uid = mudid.indexOf("uid=");
					boolean has_mudid = false;
					if (mudid != null && uid >= 0) {
						mudid = mudid.substring(uid);
						int index1 = mudid.indexOf(",");
						int index2 = mudid.indexOf(")");
						mudid = mudid.substring("uid=".length(),
								Math.min(index1, index2));
						has_mudid = true;
					}
					String emailName = bcuser[0].getDefaultName().getValue();
					output += emailName;
					if (has_mudid) {
						// emailName=mudid;
						output += "(" + mudid + ")";
					}
					output += ";\r\n";
				
			}
			
		}
		
		return output;
	}

	public void getChildrenFolder(CognosClient cognosClient, String searchPath) {
		ContentManagerServiceStub cmServiceStub = (ContentManagerServiceStub) cognosClient
				.getService("ContentManagerService");
		PropEnum[] props = { PropEnum.searchPath, PropEnum.defaultName,
				PropEnum.members };
		Sort[] sortArray = { new Sort() };
		BaseClass[] folderes = null;
		BaseClass[] pkgs = null;
		try {
			folderes = cmServiceStub.query(new SearchPathMultipleObject(
					searchPath + "/folder"), props, sortArray,
					new QueryOptions());
			pkgs = cmServiceStub.query(new SearchPathMultipleObject(searchPath
					+ "/package"), props, sortArray, new QueryOptions());
			for (BaseClass folder : folderes) {
				if (folder.getSearchPath().getValue()
						.equals("/content/folder[@name='Samples']")
						|| folder
								.getSearchPath()
								.getValue()
								.equals("/content/folder[@name='Samples_PowerCube']"))
					continue;
				if(!folder.getSearchPath().getValue()
				.equals("/content/folder[@name='Model']")){
					folders.add(folder.getSearchPath().getValue());
				}
				getChildrenFolder(cognosClient, folder.getSearchPath()
						.getValue());

			}
			for (BaseClass pkg : pkgs) {
				packages.add(pkg.getSearchPath().getValue());
				getChildrenFolder(cognosClient, pkg.getSearchPath().getValue());
			}
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		CognosClient cognosClient = CognosHelper.getClient();
//		cognosClient.setDispatch("http://shasx011:9300/p2pd/servlet/dispatch");
//		cognosClient.setUsername("oax62349");
//		cognosClient.setPassword("etk6JaV6");
//		cognosClient.setNamespace("SED");
		cognosClient.setDispatch("http://103.229.213.252:9300/p2pd/servlet/dispatch");
		try {
			cognosClient.logon();
			// System.out.println("logon success!");
		} catch (LoginException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out
					.println("Connect to Cognos failed, please check username & pasword in config.xml or Cognos enviroment.");
			return;
		}

		OutputAuthMember oam = new OutputAuthMember();
		oam.getChildrenFolder(cognosClient, "/content");
		String output = "";
		output += "=========FOLDER=========\r\n";
		for (int i = 0; i < oam.folders.size(); i++) {
			String folder = oam.folders.get(i);
			String searchpath = folder;
			output += oam.getRolePerFromCogObj(cognosClient, searchpath);
			output += "\r\n";
		}
		File file = new File("D:/data/authList_Folder.txt");
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(file);
			fos.write(output.getBytes());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			fos.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		output = "=========PACKAGES=========\r\n";
		for (int i = 0; i < oam.packages.size(); i++) {
			String pkg = oam.packages.get(i);
			String searchpath = pkg;
			output += oam.getRolePerFromCogObj(cognosClient, searchpath);
			output += "\r\n";
		}
//		file = new File("C:/Users/cz902811/Documents/authList_Package.txt");
		try {
			fos = new FileOutputStream(file);
			fos.write(output.getBytes());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			fos.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}
